home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / ASSEMBLE / H145.ZIP / ASXXXX_3.ZIP / M09MCH.C < prev    next >
C/C++ Source or Header  |  1990-07-18  |  7KB  |  463 lines

  1. /* M09MCH:C */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <setjmp.h>
  14. #include "asm.h"
  15. #include "m6809.h"
  16.  
  17. #define    NB    256
  18.  
  19. int    *bp;
  20. int    bm;
  21. int    bb[NB];
  22.  
  23. /*
  24.  * Process a machine op.
  25.  */
  26. VOID
  27. machine(mp)
  28. struct mne *mp;
  29. {
  30.     register op, rf, cpg, c;
  31.     struct expr e1;
  32.     int t1, v1, v2;
  33.     struct area *espa;
  34.     char id[NCPS];
  35.  
  36.     cpg = 0;
  37.     op = mp->m_valu;
  38.     switch (rf = mp->m_type) {
  39.  
  40.     case S_SDP:
  41.         e1.e_mode = 0;
  42.         e1.e_flag = 0;
  43.         e1.e_addr = 0;
  44.         e1.e_base.e_ap = NULL;
  45.         espa = NULL;
  46.         if (more()) {
  47.             expr(&e1, 0);
  48.             if (e1.e_flag == 0 && e1.e_base.e_ap == NULL) {
  49.                 if (e1.e_addr & 0xFF) {
  50.                     err('b');
  51.                 }
  52.             }
  53.             if ((c = getnb()) == ',') {
  54.                 getid(id, -1);
  55.                 espa = alookup(id);
  56.                 if (espa == NULL) {
  57.                     err('u');
  58.                 }
  59.             } else {
  60.                 unget(c);
  61.             }
  62.         }
  63.         if (espa) {
  64.             outdp(espa, &e1);
  65.         } else {
  66.             outdp(dot.s_area, &e1);
  67.         }
  68.         lmode = SLIST;
  69.         break;
  70.  
  71.     case S_INH2:
  72.         cpg += 0x01;
  73.  
  74.     case S_INH1:
  75.         cpg += 0x10;
  76.  
  77.     case S_INH:
  78.         if (cpg)
  79.             outab(cpg);
  80.         outab(op);
  81.         break;
  82.  
  83.     case S_BRA:
  84.         expr(&e1, 0);
  85.         outab(op);
  86.         if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
  87.             v1 = e1.e_addr - dot.s_addr - 1;
  88.             if ((v1 < -128) || (v1 > 127))
  89.                 aerr();
  90.             outab(v1);
  91.         } else {
  92.             outrb(&e1, R_PCR);
  93.         }
  94.         if (e1.e_mode != S_USER)
  95.             rerr();
  96.         break;
  97.  
  98.     case S_LBRA:
  99.         cpg += 0x10;
  100.  
  101.     case S_LBSR:
  102.         expr(&e1, 0);
  103.         if (cpg)
  104.             outab(cpg);
  105.         outab(op);
  106.         if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
  107.             v1 = e1.e_addr - dot.s_addr - 2;
  108.             outaw(v1);
  109.         } else {
  110.             outrw(&e1, R_PCR);
  111.         }
  112.         if (e1.e_mode != S_USER)
  113.             aerr();
  114.         break;
  115.  
  116.     case S_PULS:
  117.         v1 = 0;
  118.         do {
  119.             if ((t1 = admode(stks)) == 0 || v1 & t1)
  120.                 aerr();
  121.             v1 |= t1;
  122.         } while (more() && comma());
  123.         outab(op);
  124.         outab(v1);
  125.         break;
  126.  
  127.     case S_PULU:
  128.         v1 = 0;
  129.         do {
  130.             if ((t1 = admode(stku)) == 0 || v1 & t1)
  131.                 aerr();
  132.             v1 |= t1;
  133.         } while (more() && comma());
  134.         outab(op);
  135.         outab(v1);
  136.         break;
  137.  
  138.     case S_EXG:
  139.         v1 = admode(regs);
  140.         comma();
  141.         v2 = admode(regs);
  142.         if ((v1 & 0x08) != (v2 & 0x08))
  143.             aerr();
  144.         outab(op);
  145.         outab((v1<<4)|v2);
  146.         break;
  147.  
  148.     case S_ACC:
  149.         t1 = addr(&e1);
  150.         if (t1 == S_IMMED)
  151.             e1.e_mode = S_IMB;
  152.         genout(cpg, op, rf, &e1);
  153.         break;
  154.  
  155.     case S_STR1:
  156.         cpg += 0x10;
  157.  
  158.     case S_SOP:
  159.     case S_STR:
  160.         t1 = addr(&e1);
  161.         if (t1 == S_IMMED)
  162.             e1.e_mode = S_IMER;
  163.         genout(cpg, op, rf, &e1);
  164.         break;
  165.  
  166.     case S_LR2:
  167.         cpg += 0x01;
  168.  
  169.     case S_LR1:
  170.         cpg += 0x10;
  171.  
  172.     case S_LR:
  173.         t1 = addr(&e1);
  174.         if (t1 == S_IMMED)
  175.             e1.e_mode = S_IMW;
  176.         genout(cpg, op, rf, &e1);
  177.         break;
  178.  
  179.     case S_LEA:
  180.         t1 = addr(&e1);
  181.         if (index) {
  182.             genout(cpg, op, rf, &e1);
  183.             break;
  184.         }
  185.         aerr();
  186.         break;
  187.  
  188.     case S_CC:
  189.         t1 = addr(&e1);
  190.         if (t1 == S_IMMED) {
  191.             e1.e_mode = S_IMB;
  192.             genout(cpg, op, rf, &e1);
  193.             break;
  194.         }
  195.         aerr();
  196.         break;
  197.  
  198.     case S_6800:
  199.         m68out(op);
  200.         break;        
  201.  
  202.     default:
  203.         err('o');
  204.     }
  205. }
  206.  
  207. /*
  208.  * General Output Routine
  209.  */
  210. VOID
  211. genout(cpg, op, rf, esp)
  212. register int cpg, op, rf;
  213. register struct expr *esp;
  214. {
  215.     int espv;
  216.     struct area *espa;
  217.     int disp, flag;
  218.  
  219.     espv = esp->e_addr;
  220.     espa = esp->e_base.e_ap;
  221.     switch (esp->e_mode) {
  222.  
  223.     case S_IMB:
  224.         if (cpg)
  225.             outab(cpg);
  226.         outab(op);
  227.         outrb(esp, R_NORM);
  228.         break;
  229.  
  230.     case S_IMW:
  231.         if (cpg)
  232.             outab(cpg);
  233.         outab(op);
  234.         outrw(esp, R_NORM);
  235.         break;
  236.  
  237.     case S_DIR:
  238.         if (cpg)
  239.             outab(cpg);
  240.         if (rf == S_SOP) {
  241.             outab(op&0x0F);
  242.         } else {
  243.             outab(op|0x10);
  244.         }
  245.         outrb(esp, R_PAG);
  246.         break;
  247.  
  248.     case S_EXT:
  249.         if (cpg)
  250.             outab(cpg);
  251.         if (index) {
  252.             outab(op|0x20);
  253.             outab(index|0x0F);
  254.             outrw(esp, R_NORM);
  255.             break;
  256.         }
  257.         outab(op|0x30);
  258.         outrw(esp, R_NORM);
  259.         break;
  260.  
  261.     case S_IND:
  262.         if (cpg)
  263.             outab(cpg);
  264.         outab(op|0x20);
  265.         outab(index);
  266.         break;
  267.  
  268.     case S_PC:
  269.         if (espa) {
  270.             aerr();
  271.             break;
  272.         }
  273.         if (cpg)
  274.             outab(cpg);
  275.         outab(op|0x20);
  276.         if (pass == 0) {
  277.             dot.s_addr += 3;
  278.         } else
  279.         if (pass == 1) {
  280.             if (esp->e_addr >= dot.s_addr)
  281.                 esp->e_addr -= fuzz;
  282.             dot.s_addr += 2;
  283.             disp = esp->e_addr;
  284.             flag = 0;
  285.             if (disp<-128 || disp>127)
  286.                 ++flag;
  287.             if (setbit(flag))
  288.                 ++dot.s_addr;
  289.         } else {
  290.             if (getbit()) {
  291.                 outab(index|0x01);
  292.                 outaw(espv);
  293.             } else {
  294.                 outab(index);
  295.                 outab(espv);
  296.             }
  297.         }
  298.         break;
  299.  
  300.     case S_PCR:
  301.         if (cpg)
  302.             outab(cpg);
  303.         outab(op|0x20);
  304.         if (pass == 0) {
  305.             dot.s_addr += 3;
  306.         } else
  307.         if (espa && espa != dot.s_area) {
  308.             outab(index|0x01);
  309.             outrw(esp, R_PCR);
  310.         } else
  311.         if (pass == 1) {
  312.             if (esp->e_addr >= dot.s_addr)
  313.                 esp->e_addr -= fuzz;
  314.             dot.s_addr += 2;
  315.             disp = esp->e_addr - dot.s_addr;
  316.             flag = 0;
  317.             if (disp<-128 || disp>127)
  318.                 ++flag;
  319.             if (setbit(flag))
  320.                 ++dot.s_addr;
  321.         } else {
  322.             if (getbit()) {
  323.                 outab(index|0x01);
  324.                 disp = espv - dot.s_addr - 2;
  325.                 outaw(disp);
  326.             } else {
  327.                 outab(index);
  328.                 disp = espv - dot.s_addr - 1;
  329.                 outab(disp);
  330.             }
  331.         }
  332.         break;
  333.  
  334.     case S_OFST:
  335.         if (cpg)
  336.             outab(cpg);
  337.         outab(op|0x20);
  338.         if (pass == 0) {
  339.             dot.s_addr += 3;
  340.         } else
  341.         if (espa) {
  342.             outab(index|0x09);
  343.             outrw(esp, R_NORM);
  344.         } else
  345.         if (pass == 1) {
  346.             if (esp->e_addr >= dot.s_addr)
  347.                 esp->e_addr -= fuzz;
  348.             dot.s_addr += 1;
  349.             flag = 0;
  350.             if (espv <- 128 || espv > 127)
  351.                 ++flag;
  352.             if (setbit(flag)) {
  353.                 dot.s_addr += 2;
  354.             } else {
  355.                 flag = index & 0x10;
  356.                 if (espv <- 16 || espv > 15)
  357.                     ++flag;
  358.                 if (setbit(flag))
  359.                     ++dot.s_addr;
  360.             }
  361.         } else {
  362.             if (getbit()) {
  363.                 outab(index|0x09);
  364.                 outaw(espv);
  365.             } else {
  366.                 if (getbit()) {
  367.                     outab(index|0x08);
  368.                     outab(espv);
  369.                 } else {
  370.                     outab((index & 0x60) | (espv & 0x1F));
  371.                 }
  372.             }
  373.         }
  374.         break;
  375.  
  376.     case S_IMER:
  377.     default:
  378.         aerr();
  379.     }
  380. }
  381.  
  382. /*
  383.  * mc6800 compatibility output routine
  384.  */
  385. VOID
  386. m68out(i)
  387. int i;
  388. {
  389.     register char *ptr;
  390.     register int j;
  391.     ptr = (char *) &mc6800[i];
  392.     for (j=0; j<4 ; j++) {
  393.         if ((i = *ptr++) != 0) {
  394.             outab(i);
  395.         } else {
  396.             break;
  397.         }
  398.     }
  399. }
  400.  
  401. /*
  402.  * Machine specific initialization.
  403.  * Set up the bit table.
  404.  */
  405. VOID
  406. minit()
  407. {
  408.     bp = bb;
  409.     bm = 1;
  410. }
  411.  
  412. /*
  413.  * Store `b' in the next slot of the bit table.
  414.  * If no room, force the longer form of the offset.
  415.  */
  416. int
  417. setbit(b)
  418. {
  419.     if (bp >= &bb[NB])
  420.         return(1);
  421.     if (b)
  422.         *bp |= bm;
  423.     bm <<= 1;
  424.     if (bm == 0) {
  425.         bm = 1;
  426.         ++bp;
  427.     }
  428.     return(b);
  429. }
  430.  
  431. /*
  432.  * Get the next bit from the bit table.
  433.  * If none left, return a `1'.
  434.  * This will force the longer form of the offset.
  435.  */
  436. int
  437. getbit()
  438. {
  439.     register f;
  440.  
  441.     if (bp >= &bb[NB])
  442.         return (1);
  443.     f = *bp & bm;
  444.     bm <<= 1;
  445.     if (bm == 0) {
  446.         bm = 1;
  447.         ++bp;
  448.     }
  449.     return (f);
  450. }
  451.  
  452. /*
  453.  * The next character must be a
  454.  * comma.
  455.  */
  456. int
  457. comma()
  458. {
  459.     if (getnb() != ',')
  460.         qerr();
  461.     return(1);
  462. }
  463.